
package com.jf.cloud.order.listener;

import cn.hutool.core.collection.CollUtil;
import com.jf.cloud.api.leaf.feign.SegmentFeignClient;
import com.jf.cloud.api.order.constant.OrderStatus;
import com.jf.cloud.common.constant.DistributedIdKey;
import com.jf.cloud.common.constant.SendTypeEnum;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.bo.OrderStatusBO;
import com.jf.cloud.common.order.bo.PayNotifyBO;
import com.jf.cloud.common.order.vo.SendNotifyBO;
import com.jf.cloud.common.product.constant.PreSaleType;
import com.jf.cloud.common.product.constant.SupplierDeliveryType;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.rocketmq.config.RocketMqConstant;
import com.jf.cloud.common.util.Json;
import com.jf.cloud.common.util.PriceUtil;
import com.jf.cloud.order.service.OrderService;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

/**
 * @author zz
 * @date 2021/1/7
 */
@Component
@RocketMQMessageListener(topic = RocketMqConstant.ORDER_NOTIFY_TOPIC, consumerGroup = RocketMqConstant.ORDER_NOTIFY_TOPIC)
public class OrderNotifyConsumer implements RocketMQListener<PayNotifyBO> {

    @Autowired
    private OrderService orderService;
    @Autowired
    private RocketMQTemplate orderNotifyServiceTemplate;
    @Autowired
    private RocketMQTemplate sendNotifyToShopTemplate;
    @Autowired
    private RocketMQTemplate comboOrderMqTemplate;
    @Autowired
    private RocketMQTemplate sendNotifyToUserTemplate;
    @Autowired
    private SegmentFeignClient segmentFeignClient;

    private static final Logger LOG = LoggerFactory.getLogger(OrderNotifyConsumer.class);

    @Override
    public void onMessage(PayNotifyBO message) {
        LOG.info("订单回调开始... message: " + Json.toJsonString(message));
        List<OrderStatusBO> ordersStatus = orderService.getOrdersStatus(message.getOrderIds());
        orderService.updateByToPaySuccess(message, ordersStatus);

        SendStatus comboSendStatus = comboOrderMqTemplate.syncSend(RocketMqConstant.COMBO_ORDER_TOPIC, new GenericMessage<>(message.getOrderIds()), RocketMqConstant.TIMEOUT, RocketMqConstant.COMBO_ORDER_DELAY_LEVEL).getSendStatus();
        if (!Objects.equals(comboSendStatus, SendStatus.SEND_OK)) {
            // 消息发不出去就抛异常，因为订单回调会有多次，几乎不可能每次都无法发送出去，发的出去无所谓因为接口是幂等的
            throw new LuckException(ResponseEnum.EXCEPTION);
        }

        Integer orderType = ordersStatus.get(0).getOrderType();
        Integer preSaleType = ordersStatus.get(0).getPreSaleType();
        Integer status = ordersStatus.get(0).getStatus();
        message.setPreSaleType(preSaleType);
        message.setOrderStatus(status);
        message.setOrderType(orderType);

        // 定金预售订单付定金时不用全部分账
        boolean isPreSale = Objects.nonNull(preSaleType) && Objects.equals(preSaleType, PreSaleType.DEPOSIT.value()) && Objects.equals(status, OrderStatus.UNPAY.value());
        if (!isPreSale) {
            int supplierOrderNum = new Long(ordersStatus.stream().filter(orderStatusBO -> Objects.nonNull(orderStatusBO.getSupplierId())).count()).intValue();
            ServerResponseEntity<List<Long>> segmentEntity = segmentFeignClient.batchGetSegmentId(DistributedIdKey.MALL4CLOUD_SHOP_WALLET_LOG, ordersStatus.size() + supplierOrderNum * 2);
            if (segmentEntity.isFail()) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
            message.setShopWalletIds(segmentEntity.getData());
            LOG.info("商家钱包记录ID: {}", message.getShopWalletIds());
        }

        // 发送消息，订单支付成功
        // 通知库存扣减&&通知优惠券扣减&&团购支付成功回调&&秒杀支付成功回调&&商家分账
        SendStatus sendCouponStatus = orderNotifyServiceTemplate.syncSend(RocketMqConstant.ORDER_NOTIFY_SERVICE_TOPIC, new GenericMessage<>(message)).getSendStatus();
        if (!Objects.equals(sendCouponStatus, SendStatus.SEND_OK)) {
            LOG.error("发送消息，订单支付成功，通知库存扣减&&通知优惠券扣减&&团购支付成功回调&&秒杀支付成功回调&&商家分账&&通知用户余额支付成功失败，sendCouponStatus: {}", sendCouponStatus);
            throw new LuckException(ResponseEnum.EXCEPTION);
        }

        // 发送消息，订单支付成功，推送通知给用户
        sendMsgToUser(message, isPreSale);
    }

    private void sendMsgToUser(PayNotifyBO message, boolean isPreSale) {
        List<SendNotifyBO> notifyList = orderService.listSendNotifyBOByOrderIds(message.getOrderIds());
        for (SendNotifyBO sendNotifyBO : notifyList) {
            sendNotifyBO.setPrice(PriceUtil.toDecimalPrice(sendNotifyBO.getActualTotal()).toString());
            sendNotifyBO.setSendType(SendTypeEnum.PAY_SUCCESS.getValue());
        }
        // 订单支付成功推送消息给用户
        if (!isPreSale) {
            SendStatus sendStockStatus = sendNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(notifyList)).getSendStatus();
            if (!Objects.equals(sendStockStatus, SendStatus.SEND_OK)) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
            for (SendNotifyBO sendNotifyBO : notifyList) {
                // 代销商品为供应商发货则发送 待发货提醒给供应商
                if (Objects.nonNull(sendNotifyBO.getSupplierDeliveryType()) && Objects.equals(sendNotifyBO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY.value())) {
                    sendNotifyBO.setSendType(SendTypeEnum.USER_PAY_SUCCESS_TO_SUPPLIER.getValue());
                    sendNotifyBO.setShopId(null);
                    LOG.info("代销商品为供应商发货则发送 待发货提醒给供应商，sendNotifyBO: {}", sendNotifyBO);
                } else {
                    sendNotifyBO.setSendType(SendTypeEnum.USER_PAY_SUCCESS.getValue());
                    LOG.info("商家发货则发送 待发货提醒给商家，sendNotifyBO: {}", sendNotifyBO);
                }

            }
            if (CollUtil.isNotEmpty(notifyList)) {
                // 发送消息给商家，订单支付成功（即 待发货提醒）
                SendStatus sendShopMsgStatus = sendNotifyToShopTemplate.syncSend(RocketMqConstant.SEND_NOTIFY_TO_SHOP_TOPIC, new GenericMessage<>(notifyList.get(0))).getSendStatus();
                if (!Objects.equals(sendShopMsgStatus, SendStatus.SEND_OK)) {
                    LOG.error("发送消息给商家或供应商，订单支付成功（即 待发货提醒）失败，sendShopMsgStatus: {}", sendShopMsgStatus);
                    throw new LuckException(ResponseEnum.EXCEPTION);
                }
            }
        }
    }
}
